package com.huan.study.mybatis.interceptor;

import com.huan.study.mybatis.annotation.SensitiveData;
import com.huan.study.mybatis.handler.DecryptHandler;
import com.huan.study.mybatis.util.SpringUtils;
import lombok.extern.slf4j.Slf4j;
import org.apache.ibatis.executor.resultset.ResultSetHandler;
import org.apache.ibatis.plugin.*;
import org.springframework.beans.BeansException;
import org.springframework.core.annotation.AnnotationUtils;
import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils;

import java.sql.Statement;
import java.util.ArrayList;
import java.util.Objects;
import java.util.Properties;

/**
 * @author YanXxx
 */

@Slf4j
@Component
@Intercepts({
        @Signature(type = ResultSetHandler.class, method = "handleResultSets", args = {Statement.class})
})
public class ResultSetInterceptor implements Interceptor {


    @Override
    public Object intercept(Invocation invocation) throws Throwable {
        log.info("拦截器: ResultSetHandler");
        //取出查询的结果
        Object resultObject = invocation.proceed();
        if (Objects.isNull(resultObject)) {
            return null;
        }
        //基于selectList
        if (resultObject instanceof ArrayList) {
            ArrayList<?> resultList = (ArrayList<?>) resultObject;
            SensitiveData sensitiveData = getAnnotation(resultList.get(0));
            if (!CollectionUtils.isEmpty(resultList) && sensitiveData != null) {
                DecryptHandler decryptHandler = getDecryptHandler(sensitiveData);
                if (decryptHandler != null) {
                    for (Object result : resultList) {
                        //逐一解密
                        decryptHandler.decrypt(result);
                    }
                }
            }
            //基于selectOne
        } else {
            SensitiveData sensitiveData = getAnnotation(resultObject);
            if (sensitiveData != null) {
                DecryptHandler decryptHandler = getDecryptHandler(sensitiveData);
                if (decryptHandler != null) {
                    decryptHandler.decrypt(resultObject);
                }
            }
        }
        return resultObject;
    }

    private DecryptHandler getDecryptHandler(SensitiveData sensitiveData) {
        String decryptMethod = sensitiveData.decryptMethod();
        try {
            return SpringUtils.getBean(decryptMethod);
        } catch (BeansException e) {
            log.error("no such bean like:{}", decryptMethod);
            return null;
        }
    }

    private SensitiveData getAnnotation(Object object) {
        Class<?> objectClass = object.getClass();
        return AnnotationUtils.findAnnotation(objectClass, SensitiveData.class);
    }


    @Override
    public Object plugin(Object target) {
        return Plugin.wrap(target, this);
    }

    @Override
    public void setProperties(Properties properties) {

    }
}

